#include <iostream>
#include <vector>

/*
 * 线性表是一种逻辑结构，按照存储结构可以分为顺序表和链表
 *
 * 
*/
/* vector 本质上是一个动态变长数组，顺序表，连续的存储空间，访问的时间复杂度为O(1),对于尾部元素的插入和删除时间复杂度都是常量级别的
 * vector 也是一个类模板，vector底层本质就是一个顺序表，它是一个可变长的数组，采用连续存储的空间来存储数据，它的元素类型也可以是任意的内置类型或者自定义类型。
 * 对于vector的扩容机制，Linux一般是以2的倍数增加，VS一般是以1.5的倍数增加，增加快的性能会比较好，但是对空间的浪费会增大；
 * vector扩容是开辟一段新的空间，将旧的数据拷贝到新的空间
*/
/*
 * 扩容 vec.resize(n)  vec.reserve(n)
*/

int main(int argc, char *argv[])
{
    
    std::vector<int> vec = {1, 2, 3, 4, 5};
    // vec.begin()+2 代表从第三个元素开始，vec。begin()代表从第一个元素开始
    std::vector<int> vec1(vec.begin()+2,vec.end()); // = vec
    std::vector<int> vec2(vec); // = vec
    std::vector<int> vec3(4); // [0,0,0,0]
    std::vector<int> vec4(2,4); // [4,4]

    // vec.erase(vec.begin()+1); // 删除第二个元素

    vec.erase(vec.begin(),vec.begin()+1);//删除[1,3) 删除两个元素


    for (auto i : vec1) {
        std::cout << i << " ";
        std::cout << "*******" << std::endl;
    }
    vec.push_back(18); //在尾部插入一个元素
    std::cout << "Front1: " << vec.front() << std::endl;
    std::cout << "Back1: " << vec.back() << std::endl;
    vec.pop_back(); // 弹出尾部的元素
    vec.insert(vec.begin()+4,3,99);
    for (int i = 0;i < vec.size();i++)
    {
        // std::cout << "vec(" << i << "): " << vec[i] << std::endl;
        std::cout << "vec(" << i << "): " << vec.at(i) << std::endl;
        
    }

    for (int i = 0;i < vec.size();i++)
    {
        std::cout << i << " : " << vec.data()[i] << std::endl;
    }
    std::cout << "*********" << std::endl;

    std::vector<int>::iterator it;
    for (it = vec.begin();it != vec.end();it++)
    {
        std::cout << " " << " : " << *it << std::endl;
    }
    std::cout << "*********" << std::endl;

    for (auto it = vec.begin();it != vec.end();it++)
    {
        std::cout << " " << " : " << *it << std::endl;
    }
    std::cout << "*********" << std::endl;
    // 返回常量迭代器的元素
    for (auto it = vec.cbegin();it != vec.cend();it++)
    {
        std::cout << " " << " : " << *it << std::endl;
    }
    std::cout << "*********" << std::endl;

    // 逆序返回常量迭代器的元素
    for (auto it = vec.rbegin();it != vec.rend();it++)
    {
        std::cout << " " << " : " << *it << std::endl;
    }
    std::cout << "*********" << std::endl;

    std::cout << "size: " << vec.size() << " Capacity: " << vec.capacity() << std::endl;

    vec.clear();
    /* vec.resize(n) resize的扩容不会改变容器中原来的值，这里默认对扩容的部分初始化为0
     * n > capacity 时 ，可以对vector进行扩容,此时 size = capacity = n,n 为任意的大于原来capacity的值
     * n < capacity 时，不能对vector进行扩容，此时 size = n,但是 capacity 仍然与原来的capacity 相等
     * vec.reserve(n) 是指将容器的容量改为n,容器中的数据的个数不做改变也就是，不会对vec.size() 做改变
     * n > capacity 时 ，可以仅仅对容器进行扩容，此时size保持不变，capacity = n
     * n < capacity 时 ，不做任何的改变，对size 和capacity没有任何影响
     * vec.assign(n,0) assign的扩容会改变容器中原来的值，第二个参数就是需要改变后的值
     * n > capacity 时 ，可以对vector进行扩容,此时 size = capacity = n,n 为任意的大于原来capacity的值
     * n < capacity 时，不能对vector进行扩容，此时 size = n,但是 capacity 仍然与原来的capacity 相等
     * 总之，对于vector容器只能增大其容量，不能减小其容量
    */
    vec.push_back(12);
    vec.push_back(13);
    
    // vec.resize(13);
    vec.assign(13,0);
    // vec.reserve(13);  // 仅仅改变capacity 的大小
    std::cout << "Resize size: " << vec.size() << " Capacity: " << vec.capacity() << std::endl;

    std::cout << "size: " << vec.size() << " vec = [ ";
    for (int i = 0;i < vec.size();i++)
    {
        std::cout << vec[i] << " ";
    }
    std::cout << " ] " << std::endl; // vec.assign(13，0) 的输出结果： size: 13 vec = [ 0 0 0 0 0 0 0 0 0 0 0 0 0  ]  vec.resize(13) 的输出结果： size: 13 vec = [ 12 13 0 0 0 0 0 0 0 0 0 0 0  ] 

    for (int i = 0;i < 10;i++)
    {
        vec.push_back(i);
    } // 需要对vector进行扩容，一般扩容是2的指数级别的
    
    std::cout << "After clear size: " << vec.size() << " Capacity: " << vec.capacity() << std::endl;

    if (vec.empty())
    {
        std::cout << "Vec is empty!" << std::endl;
    }

    std::vector<int> vecT[3];// vector 定义二维数组

    for (int i = 0;i < 3;i++)
    {
        vecT[i].push_back(i);
        std::cout << "vecT" << i << " size: " << vecT[i].size() << std::endl;
    }

    std::vector<std::vector<int>> vecT1;// vector 定义二维数组
    vecT1.resize(5);//5 行
    for (int i = 0;i < 5;i++)
    {
        vecT1[i].resize(10);//10 列
    }
    for (int i = 0;i < vecT1.size();i++)
    {
        for (int j = 0;j < vecT1[i].size();j++)
        {
            vecT1[i][j] = i*j;
        }
    }

    for (int i = 0;i < vecT1.size();i++)
    {
        for (int j = 0;j < vecT1[i].size();j++)
        {
            std::cout << vecT1[i][j] << " ";
        }
    }
    std::cout << std::endl;
    

    return 0;
}

